package main

import (
	"fmt"
	"sync"
)

/**
会panic的几种情况
1.向已经关闭的channel发送数据
2.关闭已经关闭的channel
3.关闭未初始化的nil channel

会阻塞的情况：
1. 从未初始化nil channel中读数据
2. 向未初始化nil channel中发数据
3.在没有读取的groutine时，向无缓冲channel发数据
4.在没有数据时，从无缓冲channel读数据
返回零值:
从已经关闭的channe接收数据
 */
type Person struct {
	Age int `json:"age"`
}

func main() {
	num := 10
	var wg sync.WaitGroup
	c := make(chan Person)
	for i := 1; i < num; i++ {
		wg.Add(1)
		go testChannel(c, &wg)
	}

	// 等待关闭channel
	go func() {
		wg.Wait()
		close(c)
	}()

	//如果把上面注释掉，启用下面，就会报错。问题：为什么要放到协程里去wait和close才行。因为接收和写入得同时进行
	//wg.Wait()
	//close(c)

	// 读取数据
	for i := range c {
		fmt.Println(i.Age)
	}

}

func testChannel(c chan Person, wg *sync.WaitGroup) {
	c <- Person{Age: 1} // channl是协程安全的
	defer wg.Done()
}
